package com.apes.fn.serveControl.serverChildPackage;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.serveControl.serverParentPackage.PControlService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.query.SqlService;
import com.apes.framework.util.Arith;
import com.apes.framework.util.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 技术审核
 * Creator: zouyc
 * CreateDate: 2021-03-11 13:44
 * Description:
 **/
@Service("techAuditService")
public class TechAuditService extends PControlService {
    @Autowired
    SqlService sqlService;

    /**
     * 绿色矩形：发起技术审核月总单量，多次发起的计多次；
     * 红色矩形：技术审核超时月总单量，按超时的节点计算；
     * 平均耗时：月总单量耗时/月总单量;
     * 柱形图
     * @param req
     * @return
     */
    public List qryTechDiagramm(SimpleRequest req){
        List reList= checkAndReturnList( MapUtil.mapped(req.getJO()));
        //获取基础数据，进行分组

        JSONArray reArray = Optional.ofNullable(
                PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.qryTechControl",new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))))))
        ).orElseGet(()->createArray());

        Map groupMap = reArray.stream().collect(Collectors.groupingBy( item -> groupBy(item) ));

        reList.forEach(reJson ->{
            JSONObject reJsonTemp = (JSONObject) reJson;
            groupMap.forEach((k,v) ->{
                List vArray = (List) v;
                if(k.equals(reJsonTemp.get("mouth"))) {
                    int allAmount = (int) vArray.stream().mapToDouble(item -> getSumDoubl(item, "AMOUNT")).sum();
                    int exAmount = (int) vArray.stream().filter(item -> {
                        JSONObject item1 = (JSONObject) item;
                        return expiredBoolean(item1);
                    }).mapToDouble(item -> getSumDoubl(item, "AMOUNT")).sum();
                    int allTime = (int) vArray.stream().mapToDouble(item -> getSumDoubl(item, "SUMTIME")).sum();
                    reJsonTemp.put("greenModul", allAmount);
                    reJsonTemp.put("redModul", exAmount);
                    reJsonTemp.put("lineModul", allAmount == 0 ? 0 : Arith.round(allTime / allAmount, 2));
                }
            });
            if(reJsonTemp.get("greenModul") == null) reJsonTemp.put("greenModul",0);
            if(reJsonTemp.get("redModul") == null) reJsonTemp.put("redModul",0);
            if(reJsonTemp.get("lineModul") == null) reJsonTemp.put("lineModul",0);
        });
        return reList;
    }

    /**
     * 技术审核漏斗
     * @param req
     * @return
     */
    public List qryTechLeak(SimpleRequest req){
        checkAndReturnList(MapUtil.mapped(req.getJO()));
        List reList = new ArrayList();

        try {
            JSONArray toArray = Optional.ofNullable(
                    PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.toTech",new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))))))
            ).orElseGet(()->createArray());
            int allSize = toArray.getJSONObject(0).getInteger("AMOUNT");
            JSONArray techArray = Optional.ofNullable(
                    PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.tech",new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))))))
            ).orElseGet(()->createArray());
            JSONArray confirmArray = Optional.ofNullable(
                    PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.confirm",new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))))))
            ).orElseGet(()->createArray());
            JSONArray receArray = Optional.ofNullable(
                    PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.receiveble",new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))))))
            ).orElseGet(()->createArray());
            techArray.forEach(item -> aculate(item,allSize));
            confirmArray.forEach(item -> aculate(item,allSize));
            receArray.forEach(item -> aculate(item,allSize));

            reList.addAll(toArray);
            reList.addAll(techArray);
            reList.addAll(confirmArray);
            reList.addAll(receArray);
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        return reList;
    }
    /**
     * 传入开始和终止时间，构建一个月份数组，再将数据匹配进去
     * @param req
     * @return
     */
    public List qryLineCharAmout(SimpleRequest req){
        List reList=checkAndReturnList( MapUtil.mapped(req.getJO()));
        com.apestech.framework.json.JSONObject conditionJson = new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))));
        JSONArray line1 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar1",conditionJson));
        JSONArray line2 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar2",conditionJson));
        JSONArray line3 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar3",conditionJson));
        JSONArray line4 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar4",conditionJson));
        try {
            //获取需要数据
            reList.forEach(item ->{
                JSONObject listJson = (JSONObject)item;
                try {
                    listJson.put("line1",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line1).orElseGet(()->createArray()),"AMOUNT"));
                    listJson.put("line2",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line2).orElseGet(()->createArray()),"AMOUNT"));
                    listJson.put("line3",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line3).orElseGet(()->createArray()),"AMOUNT"));
                    listJson.put("line4",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line4).orElseGet(()->createArray()),"AMOUNT"));
                }catch (Exception e){
                    throw new RuntimeException(e.getMessage());
                }
                JSONObject item1 = (JSONObject)item;
            });
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        return reList;
    }
    /**
     * 获取技术审核金钱坐标
     * @param req
     * @return
     */
    public List qryLineCharMoney(SimpleRequest req){
        com.apestech.framework.json.JSONObject conditionJson = new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))));
        List reList=checkAndReturnList( MapUtil.mapped(req.getJO()));
        JSONArray line1 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar1",conditionJson));
        JSONArray line2 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar2",conditionJson));
        JSONArray line3 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar3",conditionJson));
        JSONArray line4 = PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.lineChar4",conditionJson));
        try {
            reList.forEach(item ->{
                JSONObject listJson = (JSONObject)item;
                try {
                    listJson.put("line1",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line1).orElseGet(()->createArray()),"MONEY"));
                    listJson.put("line2",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line2).orElseGet(()->createArray()),"MONEY"));
                    listJson.put("line3",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line3).orElseGet(()->createArray()),"MONEY"));
                    listJson.put("line4",obtainLine(listJson.getString("mouth"),Optional.ofNullable(line4).orElseGet(()->createArray()),"MONEY"));
                }catch (Exception e){
                    throw new RuntimeException(e.getMessage());
                }
                JSONObject item1 = (JSONObject)item;
            });
        }catch (Exception e){
            throw new RuntimeException(e.getMessage());
        }
        return reList;
    }
    /**
     * 技术审核退回审核图
     * @param req
     * @return
     */
    public List qryBackPriceAudit(SimpleRequest req){
        List reList=checkAndReturnList( MapUtil.mapped(req.getJO()));
        com.apestech.framework.json.JSONObject conditionJson = new com.apestech.framework.json.JSONObject(MapUtil.mapper("DATE_START",super.returnDate(req.getJO().get("DATE_START")),"DATE_END",super.returnDate(req.getJO().get("DATE_END"))));
        JSONArray array = Optional.ofNullable(PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.backTechAudit",conditionJson))).orElseGet(()-> new JSONArray());
        reList.forEach(item ->{
            JSONObject itemTemp = (JSONObject)item;
            array.forEach(aItem ->{
                JSONObject aItemTemp = (JSONObject)aItem;
                if(itemTemp.getString("mouth").equals(aItemTemp.getString("BACK_DATE"))){
                    itemTemp.put("AMOUNT",aItemTemp.get("AMOUNT"));
                }
            });
            if(itemTemp.get("AMOUNT") == null) itemTemp.put("AMOUNT",0);
        });
        return reList;
    }
    /**
     * 技术审核退回明细
     * @param req
     * @return
     */
    public Page qryBackPriceAuditDetail(SimpleRequest req){
        JSONObject jo = req.getJO();
        Optional.ofNullable(jo.get("size")).orElseThrow(()->new RuntimeException("分页数据不能为空"));
        Optional.ofNullable(jo.get("page")).orElseThrow(()->new RuntimeException("分页数据不能为空"));
        if(jo.getInteger("size") >= 5000) throw new RuntimeException("页数据不能大于5000");
        jo.putAll(req.getJO().getJSONObject("condition"));
        JSONArray deptLsit = jo.getJSONArray("DEPT_ID");
        Map conditonMap = MapUtil.mapper("DATE_START",super.returnDate(jo.get("DATE_START")),"DATE_END",super.returnDate(jo.get("DATE_END")),"page",jo.getInteger("page"),"size",jo.get("size"));
        if(deptLsit != null && deptLsit.size()!= 0){
            conditonMap.put("DEPT_ID",deptLsit.stream().collect(Collectors.toCollection(ArrayList::new)));
        }
        com.apestech.framework.json.JSONObject conditionJson = new com.apestech.framework.json.JSONObject(conditonMap);

        List reList = Optional.ofNullable(PControlService.tranTypeArray(sqlService.queryId("TechAuditControl.backTechAuditDetail",conditionJson))).orElseGet(()->createArray())
                .stream().map(item->{
                    JSONObject json = (JSONObject)item;
                    if(json.get("AMOUNT") == null) json.put("AMOUNT",0);
                    return json;
                }).collect(Collectors.toList());

        JSONObject firstJSON = (JSONObject) reList.get(0);
        reList.remove(0);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(jo.getInteger("page"), jo.getInteger("size"), sort);
        PageImpl pPage = new PageImpl(reList, pageable, firstJSON.getJSONObject("SYS_PAGE").getInteger("Total"));
        return pPage;
    }

    public List mouthTechAudit(SimpleRequest req){
        JSONObject jo = req.getJO();
        super.check(returnDate(jo.get("DATE_START")),returnDate(jo.get("DATE_END")));
        com.apestech.framework.json.JSONObject json1 = new com.apestech.framework.json.JSONObject();
        json1.put("DATE_START",returnDate(jo.get("DATE_START")));
        json1.put("DATE_END",returnDate(jo.get("DATE_END")));
        JSONArray array = tranTypeArray(sqlService.queryId("TechAuditControl.mouthTechAudit",json1));

        //根据人员分组
        Map map = array.stream().collect(Collectors.groupingBy(item->{
            return ((JSONObject)item).getString("EXECUTOR_ID");
        }));
        List list = new ArrayList();
        map.forEach((k,v)->{
            List vList = (ArrayList)v;
            Double amount = vList.stream().mapToDouble(dItem->{ return ((JSONObject)dItem).getDoubleValue("AMOUNT");}).sum();
            Double b_amount = vList.stream().filter(dItem ->{
                return ((JSONObject)dItem).getBoolean("EXPIRED");
            }).mapToDouble(dItem->{ return ((JSONObject)dItem).getDoubleValue("AMOUNT");}).sum();
            Double time = vList.stream().mapToDouble(dItem->{ return ((JSONObject)dItem).getDoubleValue("TIME");}).sum();

            String EXECUTOR_NAME = ((JSONObject)(vList.stream().findFirst().get())).getString("EXECUTOR");
            String WORKLOCATION = ((JSONObject)(vList.stream().findFirst().get())).getString("WORK_POST");

            JSONObject reJson = new JSONObject();
            reJson.put("WORKLOCATION",WORKLOCATION);
            reJson.put("EXECUTOR_ID",k);
            reJson.put("EXECUTOR_NAME",EXECUTOR_NAME);
            reJson.put("TIME",amount == 0 ? 0 : Arith.round(time /amount,2));
            reJson.put("AMOUNT",amount);
            reJson.put("B_MOUNT",b_amount);

            reJson.put("L_B_MOUNT",b_amount);
            reJson.put("L_AMOUNT",amount);
            reJson.put("L_B_MOUNT",b_amount);
            list.add(reJson);
        });
        return list;
    }
}